/**
* @file FileOperator.h
* @brief This file is intended to provide all the interface with input and output file
*
* The input of the physical parameters and initial conditions of the problems are defined in 
* the formatted text. The first function of  the file operator is to read all the input file, 
* preparing data of the calculation process. (However, the normalized process is not done here.) 
* The second part of this file oprator is to write the output value. The Poisson problem class 
* is responsible for preparing the data and conversing the normalized data to real value. 
*
* @author lunzhy
* @date 2013-5-17   11:28
* @note 
* 1) Initially, the data is normalized while it's read in the file operator. This was considered 
* to be more efficient. However currently all the normalization process is done after reading in 
* in the Poisson problem class.
* 2) The data-reading consequence must be in the same order with the process of normalization and 
* vector loading in the problem class.
* @todo
*/
#pragma once
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include "Utilities.h"
using namespace Utilities;


/// @brief read the input file and output the values after calculation
class FileOperator
{
private:
	std::string fileName;
	static const int infoLinesOneDim = INFO_LINES_ONE_DIM;
	static const int infoLinesTwoDim = INFO_LINES_TWO_DIM;
public:
	FileOperator(std::string filename);
	~FileOperator(void);
	/// @brief OutputVectors is used to write vectors to file with specified vector title
	/// 
	/// The number of the output vectors can be unknown. Value conversion is not done here.
	/// The file name is specified in the initialization of the FileOperator object
	/// 
	/// @param std::string & title
	/// @param std::vector<std::vector<double>> & vectors
	/// @pre the values are conversed to real values and combined in vector<vector>
	/// @return void
	/// @note
	/// @see
	void OutputVectors(std::string &vectorTitle, std::vector<std::vector<double>>& vectors);
	/// @brief Output2DVector is used to output 2D vectors to file with specified title
	/// 
	/// The format of the output value is in accordance with the input format in Matlab, in which, row 
	/// represents the value of x direction. Column represents the value of y direction. For both directions,
	/// small index comes first.
	/// 
	/// @param std::string vectorTitle
	/// @param My2DVector<double> the2DVector
	/// @param bool newFile, true: create new file; false: write existing file
	/// @pre
	/// @return void
	/// @note this is for mesh or contour plotting in matlab
	/// @see
	void Output2DVectorForMatlab(std::string &vectorTitle, My2DVector<double> the2DVector, bool newFile);
	/// @brief Output2DVectorForOrigin is used to output 2D vectors with specified title to file in format used in Origin
	/// 
	/// When origin is used to draw the contour of physical values, the value of each single point is required. Each lines
	/// represents a vertex with x/y coordinates and electric potential.
	/// 
	/// @param std::string & vectorTitle
	/// @param std::vector<My2DVector<double>> the2Dvectors the vector of the 2DVector
	/// @pre
	/// @return void
	/// @note
	/// @see
	void Output2DVectorsForOrigin(std::string &vectorTitle, std::vector<My2DVector<double>> the2Dvectors);
	/// @brief ReadOneDimProblem is used to read the physical parameters of one dimensional Poisson problem
	/// 
	/// These initial physical parameters of one dimensional Poisson problem includes: grid length, relative dielectric 
	/// constant and grid charge concentration. These three values are N - vector. The read-in order is same with
	/// the parameter order of the formatted input file.
	/// 
	/// @param std::vector<double> & vec1
	/// @param std::vector<double> & vec2
	/// @param std::vector<double> & vec3
	/// @pre the formatted input parameter file
	/// @return void
	/// @note In the method, the parameters are read in their real value. The normalization is not done here.
	/// @see
	void ReadOneDimProblem(std::vector<double> &deltaX, std::vector<double> &relativeDiel, std::vector<double> &chargeConc);
	/// @brief ReadOneDimProblemInfo is used to read the grid number, left and right boundary conditions of on dimensional
	/// boundary conditions
	/// 
	/// These infos exist in the first three line of the formatted parameter input file. The process order must be in the same
	/// order of the formatted file.
	/// 
	/// @param int & gridnum
	/// @param BoundaryCondition & left
	/// @param BoundaryCondition & right
	/// @pre the formatted input parameter file
	/// @return void
	/// @note In the method, the parameters are read in their real value. The normalization is not done here.
	/// @see
	void ReadOneDimProblemInfo(int &gridnum, OneDimBC &left, OneDimBC &right);
	/// @brief ReadTwoDimProblemInfo is used to read the grid number, boundary conditions at boundaries of left, right, up and down position
	/// 
	/// This infos exit in the first five lines of the input formatted file. The read-in order must be in the same order with the formatted file
	/// 
	/// @param int & gridNumX
	/// @param int & gridNumY
	/// @param TwoDimBC & left
	/// @param TwoDimBC & right
	/// @param TwoDimBC & up
	/// @param TwoDimBC & down
	/// @pre
	/// @return void
	/// @note
	/// @see
	void ReadTwoDimProblemInfo(int &gridNumX, int &gridNumY, TwoDimBC &left, TwoDimBC &right, TwoDimBC &up, TwoDimBC &down);
	/// @brief ReadTwoDimProblem is used to read the physical and math parameters of the two dimensional Poisson problem
	/// 
	/// These input parameters include mesh informations on X and Y direction, the relative dielectric and charge concentration of every grid.
	/// The mesh informations are Nx and Ny vectors respectively and the physical parameters are two dimensional values in [Nx, Ny].
	/// The order of the physical parameters are defined in the formatted input file, which is positive-x-direction major. 
	/// 
	/// @param std::vector<double> & meshx
	/// @param std::vector<double> & meshy
	/// @param My2DVector<double> & relativeDiel
	/// @param My2DVector<double> & chargeConc
	/// @pre
	/// @return void
	/// @note
	/// @see
	void ReadTwoDimProblem(std::vector<double> &meshx, std::vector<double> &meshy, My2DVector<double> &relativeDiel, My2DVector<double> &chargeConc);
};

